import tkinter as tk
from PIL import Image, ImageTk
import numpy as np
import json

# 创建一个卷积神经网络的类，方便调用
class CNN:
    # 构造函数（数组大小，卷积核大小，卷积核数量）
    # 通俗理解（原图大小，探照灯大小，探照灯的数量）
    def __init__(self, shape, size, filters):
        self.shape = shape
        self.size = size
        self.filters = filters
        # 权重（斜率）
        self.weights = self.Weights()
        # 偏置（截距）
        self.biases = self.Biases()

    # 初始化权重（斜率）
    def Weights(self):
        weights = []
        for i in range(self.filters):
            # 生成小图片的二维数组
            filter = []
            for row in range(self.size):
                filter.append([])
                for col in range(self.size):
                    # 随机权重值
                    filter[row].append(np.random.rand())
            weights.append(filter)
        return weights

    # 初始化偏置量（截距）
    def Biases(self):
        biases = []
        for b in range(self.filters):
            biases.append(np.random.rand())
        return biases

    # 前向传播
    def Forward(self, input):
        # 计算与输出的次数（二维数组）
        output = np.zeros((input.shape[0] - self.size + 1, input.shape[1] - self.size + 1))
        # 开始循环计算（真实项目中可以并行计算）
        for i in range(input.shape[0] - self.size + 1):
            for j in range(input.shape[1] - self.size + 1):
                for k in range(self.filters):
                    for x in range(self.size):
                        for y in range(self.size):
                            # 矩阵（数组）相乘再求和
                            output[i][j] += input[i + x][j + y] * self.weights[k][x][y]
                    output[i][j] += self.biases[k]
        return output

# 主函数
def main(val):
    if val == "":
        return
    # 图片数据处理
    img = Image.open(val)
    w, h = img.size
    # 绘制图片
    cs = tk.Canvas(root, width=w, height=h)
    cs.pack()
    img_tk = ImageTk.PhotoImage(img)
    cs.image = img_tk
    cs.create_image(0, 0, anchor=tk.NW, image=img_tk)

    # 获得图片信息
    inputs = []
    # 逐行
    for row in range(h):
        inputs.append([])
        # 逐列
        for col in range(w):
            datas = img.getpixel((col, row))
            # 均值
            color = sum(datas) / 3
            # 归一
            inputs[row].append(color / 255)
    # 创建卷积神经网络
    cnn = CNN([w, h], 3, 2)
    my_module = cnn.Forward(np.array(inputs))
    # label = tk.Label(root, image=img_tk)
    # # 防止图像被垃圾回收，否则图片不显示
    # label.image = img_tk
    # label.pack()

    # 输出模型
    tk.Label(root, text='由于数据量较大，建议在终端观看').pack()
    # 建议在控制塔中观看
    print(inputs, my_module)

# 创建 Tkinter 窗口
root = tk.Tk()
root.title("卷积神经网络")
root.geometry("200x400")

# 创建选择框
options = ["请选择你要训练的图片", "3/3/img/1.png", "3/3/img/2.png", "3/3/img/3.png"]
selected = tk.StringVar()
selected.set(options[0])
option_menu = tk.OptionMenu(root, selected, *options, command=main)
option_menu.pack()

# 运行 Tkinter 主循环
root.mainloop()